package com.example.tourism.Service;

import com.example.tourism.utils.API.ERNIE_Bot_4;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.web.context.WebApplicationContext;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ERNIE_Bot_4Service {
    @Value("${tourism.app.API_KEY}")
    private String API_KEY;
    @Value("${tourism.app.SECRET_KEY}")
    private String SECRET_KEY;
    private static final String system = "你是一名导游，各个地方的景点你都了如指掌，对用户耐心且富有幽默感"; //模型人设，主要用于人设设定，例如，你是xxx公司制作的AI助手，长度1024个字节
    private List<JSONObject> messageList = new ArrayList<>();  //存放用户与模型的对话历史记录
    private static final String roleOfUser = "user";  //user: 表示用户 ；assistant: 表示对话助手 ；function: 表示函数
    private static final String roleOfAssistant = "assistant";

//    响应说明
//    名称	类型	描述
//    id	string	本轮对话的id
//    object	string	回包类型
//    chat.completion：多轮对话返回
//    created	int	时间戳
//    sentence_id	int	表示当前子句的序号。只有在流式接口模式下会返回该字段
//    is_end	bool	表示当前子句是否是最后一句。只有在流式接口模式下会返回该字段
//    is_truncated	bool	当前生成的结果是否被截断
//    result	string	对话返回结果
//    need_clear_history	bool	表示用户输入是否存在安全，是否关闭当前会话，清理历史会话信息
//                                  true：是，表示用户输入存在安全风险，建议关闭当前会话，清理历史会话信息
//                                  false：否，表示用户输入无安全风险
//    ban_round	int	当need_clear_history为true时，此字段会告知第几轮对话有敏感信息，如果是当前问题，ban_round=-1
//    usage	usage	token统计信息，token数 = 汉字数+单词数*1.3 （仅为估算逻辑）
//    function_call	function_call	由模型生成的函数调用，包含函数名称，和调用参数

    /**
     * 获取千帆大模型对话
     * 下面讲述map返回值内容
     * id  本轮对话的id
     * is_truncated  当前生成的结果是否被截断
     * result  对话返回结果
     * need_clear_history  表示用户输入是否存在安全，是否关闭当前会话，清理历史会话信息
     * ban_round  当need_clear_history为true时，此字段会告知第几轮对话有敏感信息，如果是当前问题，ban_round=-1，如果为false，则没有此字段
     * @param userId 用户id值
     * @param content 此次对话内容
     * @return map封装的返回值
     * @throws IOException IO异常
     */
    public Map<String,Object> getResponse(long userId, String content) throws IOException {
        messageList.add(new JSONObject().put("role",this.roleOfUser).put("content",content));  //向历史对话记录中添加该次对话内容
        String bodyValue = convertToJsonString(String.valueOf(userId), this.messageList);  //将各种参数转换为json字符串
        ERNIE_Bot_4 ernie_bot_4 = new ERNIE_Bot_4(API_KEY,SECRET_KEY,bodyValue);
        String response = ernie_bot_4.getResponse();
        return convertResponseToMap(response);
    }
    private Map<String,Object> convertResponseToMap(String response){
//        System.out.println(response);
        Map<String,Object> map = new HashMap<>();
        JSONObject jsonObject = new JSONObject(response);
        map.put("id",jsonObject.getString("id"));  //本轮对话的id
        map.put("is_truncated",jsonObject.getBoolean("is_truncated"));  //当前生成的结果是否被截断
        String result = jsonObject.getString("result");  //对话返回结果
        messageList.add(new JSONObject().put("role",this.roleOfAssistant).put("content",result));  //将 返回对话内容 放入对话历史记录中
        map.put("result",result);
        boolean haveBan = jsonObject.getBoolean("need_clear_history");  //表示用户输入是否存在安全，是否关闭当前会话，清理历史会话信息
        map.put("need_clear_history",haveBan);
        if(haveBan){
            map.put("ban_round",jsonObject.getInt("ban_round"));  //当need_clear_history为true时，此字段会告知第几轮对话有敏感信息，如果是当前问题，ban_round=-1
        }
        return map;
    }
    private static String convertToJsonString(String userId, List<JSONObject> messageList){
        JSONObject body = new JSONObject();
        body.put("user_id",userId);
        body.put("messages",messageList);
        body.put("system",system);
        return body.toString();
    }
}
